<?php
// +----------------------------------------------------------------------
// | EpisodeAllocation 类型服务
// +----------------------------------------------------------------------
// | 主要服务于EpisodeAllocation数据处理
// +----------------------------------------------------------------------
// | 错误编码头 208xxx
// +----------------------------------------------------------------------

namespace common\service;


use think\Exception;
use Webman\Stomp\Client;
use support\SingletonTrait;
use common\model\EntityModel;
use common\model\EntityEpisodeRelationModel;

class EntityEpisodeRelationService
{
    use SingletonTrait;

    private $entityEpisodeRelationModel;

    public function __construct()
    {
        $this->entityEpisodeRelationModel = model(EntityEpisodeRelationModel::class);
    }

    /**
     * 查询实体的关联关系
     * @param $filter
     * @return array
     */
    public function relationSelect($filter)
    {
        $count = 0;
        $rows = [];
        $entityEpisodeRelation = $this->entityEpisodeRelationModel->where($filter)->select();
        if (!empty($entityEpisodeRelation)) {
            $entityEpisodeIds = array_column($entityEpisodeRelation, 'episode_id');

            $episode = model(EntityModel::class)->where(['id' => ['IN', join(',', $entityEpisodeIds)]])->field('id,name,code')->select();
            $episode = array_column($episode, null, 'id');
            foreach ($entityEpisodeRelation as $key => $entityEpisodeRelationItem) {
                if (array_key_exists($entityEpisodeRelationItem['episode_id'], $episode)) {
                    $entityEpisodeRelationItem['episode_name'] = $episode[$entityEpisodeRelationItem['episode_id']]['name'];
                    $entityEpisodeRelationItem['episode_code'] = $episode[$entityEpisodeRelationItem['episode_id']]['code'];
                    $entityEpisodeRelation[$key] = $entityEpisodeRelationItem;
                } else {
                    unset($entityEpisodeRelation[$key]);
                }
            }
            $count = count($entityEpisodeRelation);
            $rows = array_values($entityEpisodeRelation);
        }

        return [
            'total' => $count,
            'rows' => $rows,
        ];
    }

    /**
     * 删除关联关系
     * @param $filter
     * @return int[]
     */
    public function relationDelete($filter)
    {
        $count = 0;
        $entityEpisodeRelation = $this->entityEpisodeRelationModel->where($filter)->select();
        if (!empty($entityEpisodeRelation)) {
            $deleteData = [];

            $entityIds = array_column($entityEpisodeRelation, 'entity_id');
            $entityList = model(EntityModel::class)->where([
                'id' => ['IN', join(',', $entityIds)]
            ])->field('id,name')->select();
            $entityList = array_column($entityList, 'name', 'id');
            foreach ($entityEpisodeRelation as $entityEpisodeRelationItem) {
                //剧本模块不会存在场次为空的数据 ,所以场次为空的数据应当排除掉
                if (!isset($entityList[$entityEpisodeRelationItem['entity_id']])) {
                    continue;
                }
                if (!empty($entityEpisodeRelationItem['showings_number'])) {
                    $deleteData[] = [
                        'project_id' => $entityEpisodeRelationItem['project_id'],
                        'episode_id' => $entityEpisodeRelationItem['episode_id'],
                        'name' => $entityList[$entityEpisodeRelationItem['entity_id']],
                        'showings_number' => $entityEpisodeRelationItem['showings_number']
                    ];
                }
            }

            $this->entityEpisodeRelationModel->where($filter)->delete();
            //查询剩余的还剩多少个关联关系
            $entityEpisodeRelation = $this->entityEpisodeRelationModel->where(['entity_id' => ['IN', join(',', $entityIds)]])->select();
            //同步删除剧本拆分的清单
            if (!empty($deleteData)) {
                $this->deleteEntitySyncToScript($deleteData);
            }
            $count = count($entityEpisodeRelation);
        }


        return [
            'surplus' => $count
        ];
    }


    public function deleteEntitySyncToScript($data)
    {
        $sceneData = teamones_request('teamones-script', 'entity_list_detailed_list/delete', ['data' => $data]);
        return $sceneData['data'] ?? [];
    }

    /**
     * 同步镜头的剧集关系到资产和概念
     * @param $filter
     * @return int
     * @throws Exception
     */
    public function syncShotEpisodeRelationToAsset($filter)
    {
        $page = 1;
        $designModule = module_by_code('design');
        $episodeList = model(EntityModel::class)
            ->where(['module_id' => module_by_code('episode')['id'], 'project_id' => $filter['project_id']])
            ->select();
        $episodeList = array_column($episodeList, 'id', 'code');

        $relateModule = ['asset', 'level'];
        $res = 0;
        while (true) {
            $shotList = model(EntityModel::class)
                ->field('id,name,project_id,initial_episode_code,showings_number,json')
                ->where($filter)
                ->where(['module_id' => module_by_code('shot')['id']])
                ->page($page, 500)->select();
            if (empty($shotList)) {
                break;
            }
            $scriptFillBackData = [];
            foreach ($shotList as $shotItem) {
                $insertData = [];
                $jsonFields = json_decode($shotItem['json'], true);
                foreach ($relateModule as $moduleCode) {
                    $relateField = 'shot_' . $moduleCode;
                    $designField = $moduleCode . '_design';
                    if (empty($jsonFields[$relateField])) {
                        continue;
                    }
                    $jsonFields[$relateField] = array_filter(array_map('intval', explode(',', $jsonFields[$relateField])));
                    if (empty($jsonFields[$relateField])) {
                        continue;
                    }
                    $relateDataList = model(EntityModel::class)
                        ->where(['id' => ['IN', implode(',', $jsonFields[$relateField])]])
                        ->field("id,json->>'$.{$designField}' as design_id")
                        ->select();
                    $designIdList = array_filter(array_column($relateDataList, 'design_id'));
                    $designList = [];
                    if (!empty($designIdList)) {
                        $designFields = [
                            'id',
                            'project_id',
                            'name',
                            'design_category',
                            'design_perform_species'
                        ];
                        $designList = model(EntityModel::class)
                            ->alias('design')
                            ->where(['design.id' => ['IN', implode(',', $designIdList)]])
                            ->field(transform_custom_fields($designFields, 'design'))
                            ->select();
                        $designList = array_column($designList, null, 'id');
                    }
                    foreach ($relateDataList as $relateDataItem) {
                        $insertData[] = [
                            'entity_id' => $relateDataItem['id'],
                            'entity_module_id' => module_by_code($moduleCode)['id'],
                            'episode_id' => $episodeList[$shotItem['initial_episode_code']],
                            'created' => time(),
                            'project_id' => $shotItem['project_id'],
                            'showings_number' => $shotItem['showings_number'],
                        ];
                        $res += 1;
                        if ($relateDataItem['design_id'] > 0 && isset($designList[$relateDataItem['design_id']])) {
                            $insertData[] = [
                                'entity_id' => $relateDataItem['design_id'],
                                'entity_module_id' => $designModule['id'],
                                'episode_id' => $episodeList[$shotItem['initial_episode_code']],
                                'created' => time(),
                                'project_id' => $shotItem['project_id'],
                                'showings_number' => $shotItem['showings_number'],
                            ];
                            $design = $designList[$relateDataItem['design_id']];

                            $scriptFillBackData[] = [
                                "project_id" => $shotItem['project_id'],
                                "episode_id" => $episodeList[$shotItem['initial_episode_code']],
                                "name" => $design['name'],
                                "design_category" => $design['design_category'] ?? '',
                                "showings_number" => $shotItem['showings_number'],
                                "design_perform_species" => $design['design_perform_species']
                            ];
                            $res += 1;
                        }
                    }
                }
                EntityEpisodeRelationService::getInstance()->entityAddEpisodeRelation($insertData);
            }
            if (!empty($scriptFillBackData)) {
                //同步清单数据到剧本中
                Client::send('fill_back_script_detailed_list_data', build_queue_data_with_xu(['data' => $scriptFillBackData]));
            }
            $page++;
        }
        return $res;
    }

    /**
     * 实体添加剧集关系
     * @param $relationData
     * @return bool|int|string
     * @throws \Exception
     */
    public function entityAddEpisodeRelation($relationData)
    {
        $filter = [];
        foreach ($relationData as $relationDatum) {
            $filter[] = [
                'entity_id' => $relationDatum['entity_id'],
                'episode_id' => $relationDatum['episode_id'],
                'showings_number' => $relationDatum['showings_number'],
            ];
        }
        if (empty($filter)) {
            return 0;
        }

        $filter['_logic'] = 'or';
        $existCheckList = model(EntityEpisodeRelationModel::class)->where($filter)->select();
        $existCheckMap = [];
        foreach ($existCheckList as $item) {
            $key = $item['entity_id'] . '_' . $item['episode_id'] . '_' . $item['showings_number'];
            $existCheckMap[$key] = $item;
        }
        $insertAllData = [];
        foreach ($relationData as $relationDatum) {
            $key = $relationDatum['entity_id'] . '_' . $relationDatum['episode_id'] . '_' . $relationDatum['showings_number'];
            if (isset($existCheckMap[$key])) {
                continue;
            }
            $insertAllData[] = $relationDatum;
        }

        if (empty($insertAllData)) {
            return 0;
        }
        return model(EntityEpisodeRelationModel::class)->addAll($insertAllData, [], true);
    }
}
